﻿using System;

namespace tuimg.element
{
    using tuimg.helpers;
    using tuimg.structs;

    public struct TuimgColor
    {
        internal byte r;
        internal byte g;
        internal byte b;
        internal byte a;
        public static TuimgColor Black = FromRgb(0, 0, 0);
        public static TuimgColor White = FromRgb(255, 255, 255);
        public static TuimgColor SkyBlue = FromRgb(12, 12, 255);
        private struct_32bit_color color32;
        private struct_8bit_color color8 { get; set; }
        private struct_16bit_color color16 { get; set; }
        private struct_24bit_color color24 { get; set; }
        public TuimgColor(byte r, byte g, byte b)
        {
            this.r = r;
            this.g = g;
            this.b = b;
            this.a = 255;

            color32 = new struct_32bit_color(r, g, b, a);
            color24 = new struct_24bit_color(color32);
            color8 = new struct_8bit_color(color24);
            color16 = new struct_16bit_color(color24);
        }
        public TuimgColor(byte r, byte g, byte b, byte a = 0, byte r2=0xff, byte g2=0xff, byte b2=0xff)
        {
            this.r = r;
            this.g = g;
            this.b = b;
            this.a = a;

            color32 = new struct_32bit_color(r, g, b, a);
            color24 = new struct_24bit_color(color32, r2, g2, b2);
            color8 = new struct_8bit_color(color24);
            color16 = new struct_16bit_color(color24);
        }
        internal TuimgColor(struct_8bit_color color)
        {
            color8 = color;
            color24 = new struct_24bit_color(color);
            color16 = new struct_16bit_color(color);
            this.r = color24.R;
            this.g = color24.G;
            this.b = color24.B;
            this.a = 255;
            color32 = new struct_32bit_color(color24.R, color24.G, color24.B, a);
        }
        internal TuimgColor(struct_16bit_color color)
        {
            color16 = color;
            color24 = new struct_24bit_color(color);
            color8 = new struct_8bit_color(color);
            this.r = color24.R;
            this.g = color24.G;
            this.b = color24.B;
            this.a = 255;
            color32 = new struct_32bit_color(color24.R, color24.G, color24.B, a);
        }
        public static TuimgColor FromRgb(byte r, byte g, byte b) { return new TuimgColor(r, g, b); }
        public static TuimgColor FromBgr(byte b, byte g, byte r) { return new TuimgColor(r, g, b); }
        public static TuimgColor FromRgb(byte r, byte g, byte b, byte a) { return new TuimgColor(r, g, b, a); }
        public static TuimgColor FromBgra(byte b, byte g, byte r, byte a) { return new TuimgColor(r, g, b, a); }
        public static TuimgColor FromBgr_reserved(byte b, byte g, byte r, byte reserved) { return new TuimgColor(r, g, b, 255); }
        public static TuimgColor FromRgb(byte r, byte g, byte b, byte a, byte r2, byte g2, byte b2) { return new TuimgColor(r, g, b, a, r2, g2, b2); }
        public static TuimgColor From16(byte a, byte b) { return new TuimgColor(new struct_16bit_color { color1 = a, color2 = b }); }
        public static TuimgColor From8(byte a) { return new TuimgColor(new struct_8bit_color { color = a }); }
        public bool Equal(TuimgColor colorb, int colorbit)
        {
            switch (colorbit)
            {
                case 8: return color8.color == colorb.color8.color;
                case 16: return color16.color1 == colorb.color16.color1 && color16.color2 == colorb.color16.color2;
                case 24: return color24.R == colorb.color24.R && color24.B == colorb.color24.B && color24.G == colorb.color24.G;
                case 32: return color32.R == colorb.color32.R && color32.B == colorb.color32.B && color32.G == colorb.color32.G && color32.A == colorb.color32.A;
            }
            return false;
        }
        public TuimgColor ChangeAlpha(byte alpha)
        {
            this.a = alpha;
            this.color32.A = alpha;
            return this;
        }
        public bool Similar(TuimgColor colorb, int x)
        {
            return ((helper.abs(this.a - colorb.a) + helper.abs(this.b - colorb.b) + helper.abs(this.g - colorb.g)) >>1) < x;
        }
        public byte R { get { return r; } }
        public byte G { get { return g; } }
        public byte B { get { return b; } }
        public byte A { get { return a; } }

        internal object ToBitColor(ushort bitcount = 24)
        {

            switch (bitcount)
            {
                case 8:
                    return color8;
                case 16:
                    return color16;
                case 24:
                    return color24;
                case 32:
                default:
                    return color32;
            }
        }
    }
}
